package com.mju.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mju.controller.common.JsonResult;
import com.mju.dao.AddressDao;
import com.mju.feign.clients.UserClient;
import com.mju.pojo.Address;
import com.mju.pojo.Product;
import com.mju.pojo.User;
import com.mju.service.IAddressService;
import com.mju.service.IDistrictService;
import com.mju.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class AddressServiceImpl implements IAddressService {
    @Autowired
    private AddressDao addressDao;

    @Autowired
    private UserClient userClient;

    // 注入省市区的bean
    @Autowired
    private IDistrictService districtService; // 新增收获地址需要用到

    // 从yml配置文件中，获取用户收获地址的数量
    @Value("${user.address.max-count}")
    private Integer maxCount;

    // 备注：uid和username从控制层传递过来
    @Override
    public void addNewAddress(Integer uid, String username, Address address) {
        JsonResult<User> data = userClient.getById(uid);// 主要判断用户是否存在
        User result = data.getData();
        if(result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在");
        }
        // 判断用户的收获地址数量是否达到了上限
        Integer count = addressDao.countByUid(uid);
        if(count >= maxCount) {
            throw new AddressCountLimitException("用户的收获地址数量已达上限");
        }
        // 补全uid、isdefault
        address.setUid(uid);
        Integer isDefault = count == 0 ? 1: 0; // 若为0，那么设置为默认地址
        address.setIsDefault(isDefault);
        // 补全日志
        address.setCreatedUser(username);
        address.setModifiedUser(username);
        address.setCreatedTime(new Date());
        address.setModifiedTime(new Date());

        // 前端传递过来的省市区是编号，因此通过省市区的业务层，获取名字，进而封装为address对象
        String provinceName = districtService.getNameByCode(address.getProvinceCode());
        String cityName = districtService.getNameByCode(address.getCityCode());
        String areaName = districtService.getNameByCode(address.getAreaCode());
        address.setProvinceName(provinceName);
        address.setCityName(cityName);
        address.setAreaName(areaName);

        // 插入数据
        int rows = addressDao.insert(address);
        if(rows != 1) {
            throw new InsertException("插入用户的收获地址时，产生了未知的异常。");
        }


    }

    @Override
    public List<Address> getByUid(Integer uid) {
        List<Address> addresses = addressDao.selectByUid(uid);
        // 地址显示，只显示四个数据，其余设置空，降低数据量
        // 数据：地址类型，收货人姓名，详细地址，联系电话
        for (Address address : addresses) {
            address.setUid(null);
            address.setProvinceCode(null);
            address.setCityCode(null);
            address.setAreaCode(null);
            address.setZip(null);
            //address.setIsDefault(null);
            address.setCreatedTime(null);
            address.setCreatedUser(null);
            address.setModifiedTime(null);
            address.setModifiedUser(null);
        }
        return addresses;
 }

    @Override
    public void setDefault(Integer aid, Integer uid, String username) {
        // 1. 检测是否有该收获地址
        Address result = addressDao.selectById(aid);
        if(result == null) {
            throw new AddressNotFoundException("收获地址不存在");
        }

        // 2. 检测当前的收获地址是否是属于当前用户的
        if(!result.getUid().equals(uid)) {
            throw new AccessDeniedException("非法数据访问");
        }

        // 3. 将所有收获地址设置为非默认
        Integer rows = addressDao.updateNonDefault(uid);
        if (rows < 1) {
            throw new UpdateException("更新数据时，发生了未知异常。");
        }
        // 4. 将当前用户的收获地址设置为默认收获地址
        result.setIsDefault(1);
        result.setModifiedUser(username);
        result.setModifiedTime(new Date());
        rows = addressDao.updateById(result);
        if(rows != 1) {
            throw new UpdateException("更新数据时，产生了未知异常。");
        }

    }

    @Override
    public void delete(Integer aid, Integer uid, String username) {
        // 1. 判断该收获数据是否存在
        Address result = addressDao.selectById(aid);
        if(result == null) {
            throw new AddressNotFoundException("收获地址数据不存在");
        }
        // 2. 判断是否是当前用户访问
        if(!result.getUid().equals(uid)) {
            throw new AccessDeniedException("非法数据访问");
        }
        // 3. 删除数据
        int rows = addressDao.deleteById(aid);
        if(rows != 1) {
            throw new DeleteException("删除数据时，产生未知异常");
        }
        // 4. 如果删除的是非默认地址，直接跳出程序
        if(result.getIsDefault() == 0) {
            return;
        }
        // 5. 获取当前用户的所有收获地址
        Integer count = addressDao.countByUid(uid);
        // 若删完后，没有数据的话，直接终止。
        if(count==0) {
            return;
        }
        // 6. 将最近更新的一条收获地址设置为默认地址
        Address address = addressDao.selectLastModified(uid);
        address.setIsDefault(1);
        address.setModifiedUser(username);
        address.setModifiedTime(new Date());
        rows = addressDao.updateById(address);
        if(rows != 1) {
            throw new UpdateException("更新数据时产生未知异常");
        }
    }

    @Override
    public Address getByAid(Integer aid, Integer uid) {
        Address address = addressDao.selectById(aid);
        if (address == null) {
            throw new AddressNotFoundException("收货地址数据不存在的异常");
        }
        if (!address.getUid().equals(uid)) {
            throw new AccessDeniedException("非法访问");
        }
        // 对不需要的字段，进行空处理。
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedUser(null);
        address.setCreatedTime(null);
        address.setModifiedUser(null);
        address.setModifiedTime(null);
        return address;
    }

    @Override
    public Address queryAddressByAid(Integer aid) {
        return addressDao.selectById(aid);
    }

    @Override
    public List<Address> queryAllAddressesByUid(Integer uid) {
        LambdaQueryWrapper<Address> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Address::getUid,uid);
        List<Address> addresses = addressDao.selectList(lqw);
        return addresses;
    }

    @Override
    public IPage<Address> queryAllAddressInfo(Integer currentPage, Integer pageSize) {
        IPage page = new Page<>(currentPage, pageSize);
        addressDao.selectPage(page,null);
        return page;
    }

    @Override
    public IPage<Address> queryAddressByName(Integer currentPage, Integer pageSize, String name) {
        IPage<Address> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Address> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Address::getName, name);

        addressDao.selectPage(page,lqw);
        return page;
    }

    @Override
    public IPage<Address> queryAddressByUid(Integer currentPage, Integer pageSize, Integer uid) {
        IPage<Address> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Address> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Address::getUid, uid);

        addressDao.selectPage(page,lqw);
        return page;
    }

    @Override
    public IPage<Address> queryAddressByPhone(Integer currentPage, Integer pageSize, String phone) {
        IPage<Address> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Address> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Address::getPhone, phone);

        addressDao.selectPage(page,lqw);
        return page;
    }

    @Override
    public Integer updateAddress(Integer aid, Integer uid, Address address) {
        LambdaQueryWrapper<Address> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Address::getId, aid);
        address.setModifiedTime(new Date());
        address.setModifiedUser("管理员");
        int rows = addressDao.update(address, lqw);
        if(rows!=1) {
            throw new UpdateException("修改异常");
        }
        return rows;
    }
}
